package io.github.stary1993.kite.auth.support.handler;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import io.github.stary1993.kite.core.constant.CommonConstants;
import io.github.stary1993.kite.core.constant.SecurityConstants;
import io.github.stary1993.kite.security.core.SecurityUser;
import io.github.stary1993.kite.security.handler.AuthenticationSuccessEventHandler;
import io.github.stary1993.kite.syslog.event.SysLogEvent;
import io.github.stary1993.kite.syslog.event.SysLogEventSource;
import io.github.stary1993.kite.syslog.util.SysLogUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AccessTokenAuthenticationToken;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;

/**
 * 自定义登录成功事件处理
 * @author stary1993
 */
@Slf4j
public class CustomAuthenticationSuccessEventHandler extends AuthenticationSuccessEventHandler {

	/**
	 * @param request
	 * @param response
	 * @param chain
	 * @param authentication
	 * @throws IOException
	 * @throws ServletException
	 */
	@Override
	public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authentication) throws IOException, ServletException {
		OAuth2AccessTokenAuthenticationToken accessTokenAuthentication = (OAuth2AccessTokenAuthenticationToken) authentication;
		Map<String, Object> map = accessTokenAuthentication.getAdditionalParameters();
		if (MapUtil.isNotEmpty(map)) {
			// 发送异步日志事件
			SecurityUser userInfo = (SecurityUser) map.get(SecurityConstants.DETAILS_USER);
			log.info("用户：{} 登录成功", userInfo.getName());
			SecurityContextHolder.getContext().setAuthentication(accessTokenAuthentication);
			SysLogEventSource sysLogEventSource = SysLogUtils.getSysLog();
			sysLogEventSource.setTitle("登录成功");
			String startTimeStr = request.getHeader(CommonConstants.REQUEST_START_TIME);
			if (StrUtil.isNotBlank(startTimeStr)) {
				Long startTime = Long.parseLong(startTimeStr);
				Long endTime = System.currentTimeMillis();
				sysLogEventSource.setExecutionTime(endTime - startTime);
			}
			sysLogEventSource.setBody(userInfo);
			SpringUtil.publishEvent(new SysLogEvent(sysLogEventSource));
		}
		super.onAuthenticationSuccess(request, response, chain, authentication);
	}

}
